package com.foreverwin.mes.production.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.foreverwin.mes.common.enums.HandleEnum;
import com.foreverwin.mes.core.base.FrontPage;
import com.foreverwin.mes.core.exception.BusinessException;
import com.foreverwin.mes.core.utils.CommonMethods;
import com.foreverwin.mes.core.utils.StringUtils;
import com.foreverwin.mes.meapi.model.Bom;
import com.foreverwin.mes.meapi.model.BomComponent;
import com.foreverwin.mes.meapi.model.Item;
import com.foreverwin.mes.meapi.model.ShopOrder;
import com.foreverwin.mes.meapi.service.BomComponentService;
import com.foreverwin.mes.meapi.service.BomService;
import com.foreverwin.mes.meapi.service.ItemService;
import com.foreverwin.mes.meapi.service.ShopOrderService;
import com.foreverwin.mes.production.dto.MaterialRequisitionDto;
import com.foreverwin.mes.production.mapper.MaterialRequisitionSummaryMapper;
import com.foreverwin.mes.production.model.MaterialRequisitionSummary;
import com.foreverwin.mes.production.service.MaterialRequisitionSummaryService;
import com.foreverwin.mes.production.vo.ShopOrderTaskVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * <p>
 * 领料汇总 服务实现类
 * </p>
 *
 * @author Ervin Chen
 * @since 2020-02-24
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class MaterialRequisitionSummaryServiceImpl extends ServiceImpl<MaterialRequisitionSummaryMapper, MaterialRequisitionSummary> implements MaterialRequisitionSummaryService {


    @Autowired
    private MaterialRequisitionSummaryMapper materialRequisitionSummaryMapper;
    @Autowired
    private ShopOrderService shopOrderService;
    @Autowired
    private BomComponentService bomComponentService;
    @Autowired
    private ItemService itemService;
    @Autowired
    private BomService bomService;

    @Override
    public Page<MaterialRequisitionSummary> selectPage(FrontPage<MaterialRequisitionSummary> frontPage, MaterialRequisitionSummary materialRequisitionSummary) {
        EntityWrapper<MaterialRequisitionSummary> queryWrapper = new EntityWrapper<>();
        queryWrapper.setEntity(materialRequisitionSummary);
        return super.selectPage(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public List<MaterialRequisitionSummary> selectList(MaterialRequisitionSummary materialRequisitionSummary) {
        EntityWrapper<MaterialRequisitionSummary> queryWrapper = new EntityWrapper<>();
        queryWrapper.setEntity(materialRequisitionSummary);
        return super.selectList(queryWrapper);
    }

    @Override
    public List<ShopOrderTaskVo> selectShopOrderTaskList() {
        Locale locale = LocaleContextHolder.getLocale();
        return materialRequisitionSummaryMapper.selectShopOrderTaskList(locale.getLanguage());
    }

    @Override
    public List<MaterialRequisitionDto> selectMaterialRequisitionList(List<MaterialRequisitionDto> materialRequisitionDtos) {
        String site = CommonMethods.getSite();
        List<MaterialRequisitionDto> materialRequisitionList = new ArrayList<>();

        for (MaterialRequisitionDto materialRequisitionDto : materialRequisitionDtos) {
            String shopOrder = materialRequisitionDto.getShopOrder();
            String taskNo = materialRequisitionDto.getTaskNo();
            String itemBo = materialRequisitionDto.getItemBo();
            Double taskQty = materialRequisitionDto.getTaskQty();
            String unitOfMeasure = materialRequisitionDto.getUnitOfMeasure();


            ShopOrder shopOrderBean = shopOrderService.selectById(HandleEnum.SHOP_ORDER.getHandle(site, shopOrder));
            if (shopOrderBean == null) {
                throw BusinessException.build("production.materialRequisition.shopOrderNotExist", shopOrder);
            }

            String bomBo = shopOrderBean.getPlannedBomBo();
            if (StringUtils.isBlank(bomBo)) {
                Item itemDo = itemService.selectItem(itemBo);
                bomBo = itemDo.getBomBo();
            }
            if (StringUtils.isBlank(bomBo)) {
                throw BusinessException.build("production.materialRequisition.shopOrderBomNotExist", shopOrder);
            }
            Bom bom = bomService.getBomInfo(site, bomBo);
            List<BomComponent> bomComponents = bomComponentService.listByBomBo(bom.getHandle());
            if (bomComponents.isEmpty()) {
                throw BusinessException.build("production.materialRequisition.bom.bomComponentNotExist", HandleEnum.BOM.getPart(bomBo, 1));
            }

            bomComponents.forEach(bomComponent -> {
                String componentGbo = bomComponent.getComponentGbo();
                String itemDescription = bomComponent.getItemDescription();
                String materialType = bomComponent.getMaterialType();
                Double qty = bomComponent.getQty();
                Double receivedQty = null;
                Double pickQty = null;

                if (!"3".equals(materialType)) {
                    return;
                }
                double totalNeedQty = BigDecimal.valueOf(taskQty).multiply(BigDecimal.valueOf(qty)).doubleValue();
                MaterialRequisitionSummary requisitionSummary = selectById(HandleEnum.MATERIAL_REQUISITION_SUMMARY.getHandle(site, shopOrder, taskNo, componentGbo));
                if (requisitionSummary != null) {
                    receivedQty = requisitionSummary.getReceivedQty();
                    pickQty = totalNeedQty - receivedQty;
                } else {
                    receivedQty = Double.valueOf(0);
                    pickQty = totalNeedQty;
                }

                MaterialRequisitionDto requisitionDto = new MaterialRequisitionDto();
                requisitionDto.setShopOrder(shopOrder);
                requisitionDto.setTaskNo(taskNo);
                requisitionDto.setItemBo(componentGbo);
                requisitionDto.setItemDescription(itemDescription);
                requisitionDto.setTaskQty(totalNeedQty);
                requisitionDto.setReceivedQty(receivedQty);
                requisitionDto.setPickQty(pickQty);
                requisitionDto.setUnitOfMeasure(unitOfMeasure);
                materialRequisitionList.add(requisitionDto);
            });

        }

        return materialRequisitionList;
    }

}